declare module "stay" {
  namespace Types {
    namespace Xhr {
      interface Details {
        async?: boolean;
        cookie?: string;
        data?: string | FormData;
        headers?: Record<string, string>;
        method?:
          | "GET"
          | "POST"
          | "HEAD"
          | "PUT"
          | "OPTIONS"
          | "DELETE"
          | "CONNECT"
          | "TRACE";
        nocache?: boolean;
        overrideMimeType?: Parameters<
          typeof XMLHttpRequest.prototype.overrideMimeType
        >[0];
        password?: string;
        responseType?: XMLHttpRequestResponseType;
        timeout?: typeof XMLHttpRequest.prototype.timeout;
        url: string;
        user?: string;
        onabort?: (e: Response) => void;
        onerror?: (e: Response) => void;
        onload?: (e: Response) => void;
        onloadend?: (e: Response) => void;
        onloadstart?: (e: Response) => void;
        onprogress?: (e: Response) => void;
        onreadystatechange?: (e: Response) => void;
        ontimeout?: (e: Response) => void;
      }
      interface Response {
        readonly readyState?:
          | typeof XMLHttpRequest.UNSENT
          | typeof XMLHttpRequest.OPENED
          | typeof XMLHttpRequest.HEADERS_RECEIVED
          | typeof XMLHttpRequest.LOADING
          | typeof XMLHttpRequest.DONE;
        readonly response?: typeof XMLHttpRequest.prototype.response;
        readonly responseHeaders?: ReturnType<
          typeof XMLHttpRequest.prototype.getAllResponseHeaders
        >;
        readonly responseText?: typeof XMLHttpRequest.prototype.responseText;
        readonly responseType?: XMLHttpRequestResponseType;
        readonly responseURL?: typeof XMLHttpRequest.prototype.responseURL;
        readonly status?: typeof XMLHttpRequest.prototype.status;
        readonly statusText?: typeof XMLHttpRequest.prototype.statusText;
        readonly timeout?: number;
        readonly withCredentials?: boolean;
      }
    }
    namespace Download {
      interface Details {
        timeout?: number;
        headers?: Parameters<typeof browser.downloads.download>[0]["headers"];
        name?: Parameters<typeof browser.downloads.download>[0]["filename"];
        url: Parameters<typeof browser.downloads.download>[0]["url"];
        onload?: (this: Details, e: Xhr.Response) => void;
        onprogress?: (this: Details, e: Xhr.Response) => void;
        onerror?: (this: Details, e: Xhr.Response) => void;
        ontimeout?: (this: Details, e: Xhr.Response) => void;
      }
    }
    namespace Vcl {
      type cbFunction = (
        this: cbThis,
        name: string,
        oldValue: unknown,
        newValue: unknown,
        remote: boolean,
      ) => void;
      interface cbThis {
        readonly id: number;
        readonly key: string;
        readonly cb: cbFunction;
      }
    }
    namespace OpenTab {
      interface Option {
        active?: boolean;
        insert?: boolean;
      }
      interface Result {
        close(): void;
      }
      interface PromiseResult {
        close(): void;
        tabId: number;
      }
    }
    namespace Notification {
      interface Option extends Partial<CM_Types.Notification.Option> {
        timeout?: number;
        onclick?: () => void;
      }
    }
    namespace Menu {
      type Callback = (this: {
        accessKey: string | undefined;
        caption: string;
        commandFunc: Callback;
        id: string;
        uuid: string;
      }) => void | Promise<void>;
    }
  }
}
